package com.jswl.training.springjpa.util;

/**
 * 字节数组与数值转换工具类
 */
public class ByteUtils {
    //region Public Methods

    //region To Bytes

    /**
     * 将一个16位有符号数值转换为大端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] shortToBytesBE(short value) {
        byte[] bytes = new byte[2];

        bytes[0] = (byte) ((value >> 8) & 0xFF);
        bytes[1] = (byte) (value & 0xFF);

        return bytes;
    }


    /**
     * 将一个16位无符号数值转换为大端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] unsignedShortToBytesBE(int value) {
        byte[] result = new byte[2];

        result[0] = (byte) ((value >> 8) & 0xFF);
        result[1] = (byte) (value & 0xFF);

        return result;
    }


    /**
     * 将一个16位有符号数值转换为小端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] shortToBytesLE(short value) {
        byte[] bytes = new byte[2];

        bytes[0] = (byte) (value & 0xFF);
        bytes[1] = (byte) ((value >> 8) & 0xFF);

        return bytes;
    }


    /**
     * 将一个16位无符号数值转换为小端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] unsignedShortToBytesLE(int value) {
        byte[] result = new byte[2];

        result[0] = (byte) (value & 0xFF);
        result[1] = (byte) ((value >> 8) & 0xFF);

        return result;
    }

    /**
     * 将一个32位有符号数值转换为大端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] integerToBytesBE(int value) {
        byte[] result = new byte[4];

        result[0] = (byte) ((value >> 24) & 0xFF);
        result[1] = (byte) ((value >> 16) & 0xFF);
        result[2] = (byte) ((value >> 8) & 0xFF);
        result[3] = (byte) (value & 0xFF);

        return result;
    }

    /**
     * 将一个32位有符号数值转换为小端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] integerToBytesLE(int value) {
        byte[] result = new byte[4];

        result[0] = (byte) (value & 0xFF);
        result[1] = (byte) ((value >> 8) & 0xFF);
        result[2] = (byte) ((value >> 16) & 0xFF);
        result[3] = (byte) ((value >> 24) & 0xFF);

        return result;
    }

    /**
     * 将一个32位无符号数值转换为大端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] unsignedIntegerToBytesBE(long value) {
        byte[] result = new byte[4];

        result[0] = (byte) ((value >> 24) & 0xFF);
        result[1] = (byte) ((value >> 16) & 0xFF);
        result[2] = (byte) ((value >> 8) & 0xFF);
        result[3] = (byte) (value & 0xFF);

        return result;
    }

    /**
     * 将一个32位无符号数值转换为小端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] unsignedIntegerToBytesLE(long value) {
        byte[] result = new byte[4];

        result[0] = (byte) (value & 0xFF);
        result[1] = (byte) ((value >> 8) & 0xFF);
        result[2] = (byte) ((value >> 16) & 0xFF);
        result[3] = (byte) ((value >> 24) & 0xFF);

        return result;
    }

    /**
     * 将一个64位有符号数值转换为大端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] longToBytesBE(long value) {
        byte[] result = new byte[8];

        result[0] = (byte) ((value >> 56) & 0xFF);
        result[1] = (byte) ((value >> 48) & 0xFF);
        result[2] = (byte) ((value >> 40) & 0xFF);
        result[3] = (byte) ((value >> 32) & 0xFF);
        result[4] = (byte) ((value >> 24) & 0xFF);
        result[5] = (byte) ((value >> 16) & 0xFF);
        result[6] = (byte) ((value >> 8) & 0xFF);
        result[7] = (byte) (value & 0xFF);

        return result;
    }

    /**
     * 将一个64位有符号数值转换为小端序字节数组
     *
     * @param value 输入的数值
     * @return 数值对应的字节数组
     */
    public static byte[] longToBytesLE(long value) {
        byte[] result = new byte[8];

        result[0] = (byte) (value & 0xFF);
        result[1] = (byte) ((value >> 8) & 0xFF);
        result[2] = (byte) ((value >> 16) & 0xFF);
        result[3] = (byte) ((value >> 24) & 0xFF);
        result[4] = (byte) ((value >> 32) & 0xFF);
        result[5] = (byte) ((value >> 40) & 0xFF);
        result[6] = (byte) ((value >> 48) & 0xFF);
        result[7] = (byte) ((value >> 56) & 0xFF);

        return result;
    }

    //endregion

    //region From Bytes

    /**
     * 将给定的字节数组全部或部分内容转换为16位有符号整数。
     * *转换从第一个字节开始，需要至少两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换后的16位有符号整数
     */
    public static short bytesToShortBE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToShortBE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为16位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的16位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static short bytesToShortLE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToShortLE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照大端序转换为16位无符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的16位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int bytesToUnsignedShortBE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToUnsignedShortBE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为16位无符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的16位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int bytesToUnsignedShortLE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToUnsignedShortLE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照大端序转换为32位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int bytesToIntegerBE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToIntegerBE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为32位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int bytesToIntegerLE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToIntegerLE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照大端序转换为32位无符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long bytesToUnsignedIntegerBE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToUnsignedIntegerBE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为32位无符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long bytesToUnsignedIntegerLE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToUnsignedIntegerLE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照大端序转换为64位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long bytesToLongBE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToLongBE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为64位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long bytesToLongLE(final byte[] bytes) throws IllegalArgumentException {
        return bytesToLongLE(bytes, 0);
    }

    /**
     * 将给定的字节数组全部或部分内容按照大端序转换为16位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的16位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static short bytesToShortBE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 2);

        int value0 = bytes[startIndex] << 8;
        int value1 = bytes[startIndex + 1] & 0xFF;

        return (short) (value0 | value1);
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为16位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的16位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static short bytesToShortLE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 2);

        int value0 = bytes[startIndex] & 0xFF;
        int value1 = bytes[startIndex + 1] << 8;

        return (short) (value0 | value1);
    }

    /**
     * 将给定的字节数组全部或部分内容按照大端序转换为16位无符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的16位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int bytesToUnsignedShortBE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 2);

        int value0 = (bytes[startIndex] & 0xFF) << 8;
        int value1 = bytes[startIndex + 1] & 0xFF;

        return value0 | value1;
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为16位无符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的16位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int bytesToUnsignedShortLE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 2);

        int value0 = (bytes[startIndex + 1] & 0xFF) << 8;
        int value1 = bytes[startIndex] & 0xFF;

        return value0 | value1;
    }

    /**
     * 将给定的字节数组全部或部分内容按照大端序转换为32位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int bytesToIntegerBE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 4);

        int value0 = (bytes[startIndex] & 0xFF) << 24;
        int value1 = (bytes[startIndex + 1] & 0xFF) << 16;
        int value2 = (bytes[startIndex + 2] & 0xFF) << 8;
        int value3 = bytes[startIndex + 3] & 0xFF;

        return value0 | value1 | value2 | value3;
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为32位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int bytesToIntegerLE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 4);

        int value0 = (bytes[startIndex + 3] & 0xFF) << 24;
        int value1 = (bytes[startIndex + 2] & 0xFF) << 16;
        int value2 = (bytes[startIndex + 1] & 0xFF) << 8;
        int value3 = bytes[startIndex] & 0xFF;

        return value0 | value1 | value2 | value3;
    }

    /**
     * 将给定的字节数组全部或部分内容按照大端序转换为32位无符号整数
     * UnsignedIntegerBEByteArrayToInteger
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long bytesToUnsignedIntegerBE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 4);

        long value0 = (long) (bytes[startIndex] & 0xFF) << 24;
        int value1 = (bytes[startIndex + 1] & 0xFF) << 16;
        int value2 = (bytes[startIndex + 2] & 0xFF) << 8;
        int value3 = bytes[startIndex + 3] & 0xFF;

        return value0 | value1 | value2 | value3;
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为32位无符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long bytesToUnsignedIntegerLE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 4);

        long value0 = (long) (bytes[startIndex + 3] & 0xFF) << 24;
        int value1 = (bytes[startIndex + 2] & 0xFF) << 16;
        int value2 = (bytes[startIndex + 1] & 0xFF) << 8;
        int value3 = bytes[startIndex] & 0xFF;

        return value0 | value1 | value2 | value3;
    }

    /**
     * 将给定的字节数组全部或部分内容按照大端序转换为64位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long bytesToLongBE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 8);

        long value0 = (long) (bytes[startIndex] & 0xFF) << 56;
        long value1 = (long) (bytes[startIndex + 1] & 0xFF) << 48;
        long value2 = (long) (bytes[startIndex + 2] & 0xFF) << 40;
        long value3 = (long) (bytes[startIndex + 3] & 0xFF) << 32;
        long value4 = (long) (bytes[startIndex + 4] & 0xFF) << 24;
        int value5 = (bytes[startIndex + 5] & 0xFF) << 16;
        int value6 = (bytes[startIndex + 6] & 0xFF) << 8;
        int value7 = bytes[startIndex + 7] & 0xFF;

        return value0 | value1 | value2 | value3 | value4 | value5 | value6 | value7;
    }

    /**
     * 将给定的字节数组全部或部分内容按照小端序转换为64位有符号整数
     * *转换从给定的字节序号开始，需要两个字节*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long bytesToLongLE(final byte[] bytes, int startIndex) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, 8);

        long value0 = (long) (bytes[startIndex + 7] & 0xFF) << 56;
        long value1 = (long) (bytes[startIndex + 6] & 0xFF) << 48;
        long value2 = (long) (bytes[startIndex + 5] & 0xFF) << 40;
        long value3 = (long) (bytes[startIndex + 4] & 0xFF) << 32;
        long value4 = (long) (bytes[startIndex + 3] & 0xFF) << 24;
        int value5 = (bytes[startIndex + 2] & 0xFF) << 16;
        int value6 = (bytes[startIndex + 1] & 0xFF) << 8;
        int value7 = bytes[startIndex] & 0xFF;

        return value0 | value1 | value2 | value3 | value4 | value5 | value6 | value7;
    }

    //endregion

    //region From Partial Bytes

    //region Signed Parsers

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为32位有符号整数
     * *转换从数组序号0开始，字节长度为给定的字节数组长度*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToIntegerBE(final byte[] bytes) throws IllegalArgumentException {
        if (bytes != null) {
            return partialBytesToIntegerBE(bytes, 0, bytes.length);
        } else {
            throw new IllegalArgumentException("'bytes' must not be null!");
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为32位有符号整数
     * *转换从数组序号0开始，字节长度为给定的字节数组长度*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToIntegerLE(final byte[] bytes) throws IllegalArgumentException {
        if (bytes != null) {
            return partialBytesToIntegerLE(bytes, 0, bytes.length);
        } else {
            throw new IllegalArgumentException("'bytes' must not be null!");
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为64位有符号整数
     * *转换从数组序号0开始，字节长度为给定的字节数组长度*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToLongBE(final byte[] bytes) throws IllegalArgumentException {
        if (bytes != null) {
            return partialBytesToLongBE(bytes, 0, bytes.length);
        } else {
            throw new IllegalArgumentException("'bytes' must not be null!");
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为64位有符号整数
     * *转换从数组序号0开始，字节长度为给定的字节数组长度*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToLongLE(final byte[] bytes) throws IllegalArgumentException {
        if (bytes != null) {
            return partialBytesToLongLE(bytes, 0, bytes.length);
        } else {
            throw new IllegalArgumentException("'bytes' must not be null!");
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为32位有符号整数
     * *转换从数组序号0开始，需指定要使用的字节长度*
     *
     * @param bytes 给定的字节数组
     * @param size  需要使用的字节长度
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToIntegerBE(final byte[] bytes, int size) throws IllegalArgumentException {
        return partialBytesToIntegerBE(bytes, 0, size);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为32位有符号整数
     * *转换从数组序号0开始，需指定要使用的字节长度*
     *
     * @param bytes 给定的字节数组
     * @param size  需要使用的字节长度
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToIntegerLE(final byte[] bytes, int size) throws IllegalArgumentException {
        return partialBytesToIntegerLE(bytes, 0, size);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为64位有符号整数
     * *转换从数组序号0开始，需指定要使用的字节长度*
     *
     * @param bytes 给定的字节数组
     * @param size  需要使用的字节长度
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToLongBE(final byte[] bytes, int size) throws IllegalArgumentException {
        return partialBytesToLongBE(bytes, 0, size);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为64位有符号整数
     * *转换从数组序号0开始，需指定要使用的字节长度*
     *
     * @param bytes 给定的字节数组
     * @param size  需要使用的字节长度
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToLongLE(final byte[] bytes, int size) throws IllegalArgumentException {
        return partialBytesToLongLE(bytes, 0, size);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为32位有符号整数
     * *转换从给定的字节序号开始，需指定要使用的字节长度*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @param size       需要使用的字节长度
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToIntegerBE(final byte[] bytes, int startIndex, int size) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, startIndex + size, 1, 3);

        int value0 = (bytes[startIndex] << 24) & 0xFF000000;
        int value1 = 0;
        int value2 = 0;
        if (size > 1) {
            value1 = (bytes[startIndex + 1] << 16) & 0xFF0000;
            if (size > 2) {
                value2 = (bytes[startIndex + 2] << 8) & 0xFF00;
            }
        }

        int offset = 4 - size;
        return (value0 | value1 | value2) >> (offset * 8);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为32位有符号整数
     * *转换从给定的字节序号开始，需指定要使用的字节长度*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @param size       需要使用的字节长度
     * @return 转换成的32位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToIntegerLE(final byte[] bytes, int startIndex, int size) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, startIndex + size, 1, 3);

        int index = startIndex + size - 1;
        int value0 = (bytes[index--] << 24) & 0xFF000000;
        int value1 = 0;
        int value2 = 0;
        if (size > 1) {
            value1 = (bytes[index--] << 16) & 0xFF0000;
            if (size > 2) {
                value2 = (bytes[index] << 8) & 0xFF00;
            }
        }

        int offset = 4 - size;
        return (value0 | value1 | value2) >> (offset * 8);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为64位有符号整数
     * *转换从给定的字节序号开始，需指定要使用的字节长度*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @param size       需要使用的字节长度
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToLongBE(final byte[] bytes, int startIndex, int size) throws IllegalArgumentException {
        if (size < 4) {
            return partialBytesToIntegerBE(bytes, startIndex, size);
        } else if (size == 4) {
            return bytesToIntegerBE(bytes, startIndex);
        } else {
            checkInputParametersValidation(bytes, startIndex, startIndex + size, 5, 7);

            long value0 = ((long) bytes[startIndex++] << 56) & 0xFF00000000000000L;
            long value1 = ((long) bytes[startIndex++] << 48) & 0xFF000000000000L;
            long value2 = ((long) bytes[startIndex++] << 40) & 0xFF0000000000L;
            long value3 = ((long) bytes[startIndex++] << 32) & 0xFF00000000L;
            long value4 = ((long) bytes[startIndex++] << 24) & 0xFF000000L;
            long value5 = 0;
            long value6 = 0;
            if (size > 5) {
                value5 = (bytes[startIndex++] << 16) & 0xFF0000;
                if (size > 6) {
                    value6 = (bytes[startIndex] << 8) & 0xFF00;
                }
            }

            int offset = 8 - size;
            return (value0 | value1 | value2 | value3 | value4 | value5 | value6) >> (offset * 8);
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为64位有符号整数
     * *转换从给定的字节序号开始，需指定要使用的字节长度*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @param size       需要使用的字节长度
     * @return 转换成的64位有符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToLongLE(final byte[] bytes, int startIndex, int size) throws IllegalArgumentException {
        if (size < 4) {
            return partialBytesToIntegerLE(bytes, startIndex, size);
        } else if (size == 4) {
            return bytesToIntegerLE(bytes, startIndex);
        } else {
            checkInputParametersValidation(bytes, startIndex, startIndex + size, 5, 7);

            int index = startIndex + size - 1;
            long value0 = ((long) bytes[index--] << 56) & 0xFF00000000000000L;
            long value1 = ((long) bytes[index--] << 48) & 0xFF000000000000L;
            long value2 = ((long) bytes[index--] << 40) & 0xFF0000000000L;
            long value3 = ((long) bytes[index--] << 32) & 0xFF00000000L;
            long value4 = ((long) bytes[index--] << 24) & 0xFF000000L;
            long value5 = 0;
            long value6 = 0;
            if (size > 5) {
                value5 = (bytes[index--] << 16) & 0xFF0000;
                if (size > 6) {
                    value6 = (bytes[index] << 8) & 0xFF00;
                }
            }

            int offset = 8 - size;
            return (value0 | value1 | value2 | value3 | value4 | value5 | value6) >> (offset * 8);
        }
    }

    //endregion

    //region Unsigned Parsers

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为32位无符号整数
     * *转换从数组序号0开始，字节长度为给定的字节数组长度*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToUnsignedIntegerBE(final byte[] bytes) throws IllegalArgumentException {
        if (bytes != null) {
            return partialBytesToUnsignedIntegerBE(bytes, 0, bytes.length);
        } else {
            throw new IllegalArgumentException("'bytes' must not be null!");
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为32位无符号整数
     * *转换从数组序号0开始，字节长度为给定的字节数组长度*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToUnsignedIntegerLE(final byte[] bytes) throws IllegalArgumentException {
        if (bytes != null) {
            return partialBytesToUnsignedIntegerLE(bytes, 0, bytes.length);
        } else {
            throw new IllegalArgumentException("'bytes' must not be null!");
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为用64位有符号整数表示的最多56位有效位的无符号整数
     * *转换从数组序号0开始，字节长度为给定的字节数组长度*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的用64位有符号整数表示的最多56位有效位的无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToUnsignedLongBE(final byte[] bytes) throws IllegalArgumentException {
        if (bytes != null) {
            return partialBytesToUnsignedLongBE(bytes, 0, bytes.length);
        } else {
            throw new IllegalArgumentException("'bytes' must not be null!");
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为用64位有符号整数表示的最多56位有效位的无符号整数
     * *转换从数组序号0开始，字节长度为给定的字节数组长度*
     *
     * @param bytes 给定的字节数组
     * @return 转换成的用64位有符号整数表示的最多56位有效位的无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToUnsignedLongLE(final byte[] bytes) throws IllegalArgumentException {
        if (bytes != null) {
            return partialBytesToUnsignedLongLE(bytes, 0, bytes.length);
        } else {
            throw new IllegalArgumentException("'bytes' must not be null!");
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为32位无符号整数
     * *转换从数组序号0开始，需指定要使用的字节长度*
     *
     * @param bytes 给定的字节数组
     * @param size  需要使用的字节长度
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToUnsignedIntegerBE(final byte[] bytes, int size) throws IllegalArgumentException {
        return partialBytesToUnsignedIntegerBE(bytes, 0, size);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为32位无符号整数
     * *转换从数组序号0开始，需指定要使用的字节长度*
     *
     * @param bytes 给定的字节数组
     * @param size  需要使用的字节长度
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToUnsignedIntegerLE(final byte[] bytes, int size) throws IllegalArgumentException {
        return partialBytesToUnsignedIntegerLE(bytes, 0, size);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为用64位有符号整数表示的最多56位有效位的无符号整数
     * *转换从数组序号0开始，需指定要使用的字节长度*
     *
     * @param bytes 给定的字节数组
     * @param size  需要使用的字节长度
     * @return 转换成的用64位有符号整数表示的最多56位有效位的无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToUnsignedLongBE(final byte[] bytes, int size) throws IllegalArgumentException {
        return partialBytesToUnsignedLongBE(bytes, 0, size);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为用64位有符号整数表示的最多56位有效位的无符号整数
     * *转换从数组序号0开始，需指定要使用的字节长度*
     *
     * @param bytes 给定的字节数组
     * @param size  需要使用的字节长度
     * @return 转换成的用64位有符号整数表示的最多56位有效位的无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToUnsignedLongLE(final byte[] bytes, int size) throws IllegalArgumentException {
        return partialBytesToUnsignedLongLE(bytes, 0, size);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为32位无符号整数
     * *转换从给定的字节序号开始，需指定要使用的字节长度*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @param size       需要使用的字节长度
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToUnsignedIntegerBE(final byte[] bytes, int startIndex, int size) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, startIndex + size, 1, 3);

        int value0 = (bytes[startIndex] << 24) & 0xFF000000;
        int value1 = 0;
        int value2 = 0;
        if (size > 1) {
            value1 = (bytes[startIndex + 1] << 16) & 0xFF0000;
            if (size > 2) {
                value2 = (bytes[startIndex + 2] << 8) & 0xFF00;
            }
        }

        int offset = 4 - size;
        return (value0 | value1 | value2) >>> (offset * 8);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为32位无符号整数
     * *转换从给定的字节序号开始，需指定要使用的字节长度*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @param size       需要使用的字节长度
     * @return 转换成的32位无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static int partialBytesToUnsignedIntegerLE(final byte[] bytes, int startIndex, int size) throws IllegalArgumentException {
        checkInputParametersValidation(bytes, startIndex, startIndex + size, 1, 3);

        int index = startIndex + size - 1;
        int value0 = (bytes[index--] << 24) & 0xFF000000;
        int value1 = 0;
        int value2 = 0;
        if (size > 1) {
            value1 = (bytes[index--] << 16) & 0xFF0000;
            if (size > 2) {
                value2 = (bytes[index] << 8) & 0xFF00;
            }
        }

        int offset = 4 - size;
        return (value0 | value1 | value2) >>> (offset * 8);
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照大端序转换为用64位有符号整数表示的最多56位有效位的无符号整数
     * *转换从给定的字节序号开始，需指定要使用的字节长度*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @param size       需要使用的字节长度
     * @return 转换成的用64位有符号整数表示的最多56位有效位的无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToUnsignedLongBE(final byte[] bytes, int startIndex, int size) throws IllegalArgumentException {
        if (size < 4) {
            return partialBytesToIntegerBE(bytes, startIndex, size);
        } else if (size == 4) {
            return bytesToIntegerBE(bytes, startIndex);
        } else {
            checkInputParametersValidation(bytes, startIndex, startIndex + size, 5, 7);

            long value0 = ((long) bytes[startIndex++] << 56) & 0xFF00000000000000L;
            long value1 = ((long) bytes[startIndex++] << 48) & 0xFF000000000000L;
            long value2 = ((long) bytes[startIndex++] << 40) & 0xFF0000000000L;
            long value3 = ((long) bytes[startIndex++] << 32) & 0xFF00000000L;
            long value4 = ((long) bytes[startIndex++] << 24) & 0xFF000000L;
            long value5 = 0;
            long value6 = 0;
            if (size > 5) {
                value5 = (bytes[startIndex++] << 16) & 0xFF0000;
                if (size > 6) {
                    value6 = (bytes[startIndex] << 8) & 0xFF00;
                }
            }

            int offset = 8 - size;
            return (value0 | value1 | value2 | value3 | value4 | value5 | value6) >>> (offset * 8);
        }
    }

    /**
     * 从给定的字节数组中将指定范围的内容按照小端序转换为用64位有符号整数表示的最多56位有效位的无符号整数
     * *转换从给定的字节序号开始，需指定要使用的字节长度*
     *
     * @param bytes      给定的字节数组
     * @param startIndex 转换时使用数组内容的起始序号
     * @param size       需要使用的字节长度
     * @return 转换成的用64位有符号整数表示的最多56位有效位的无符号整数
     * @throws IllegalArgumentException 输入参数异常
     */
    public static long partialBytesToUnsignedLongLE(final byte[] bytes, int startIndex, int size) throws IllegalArgumentException {
        if (size < 4) {
            return partialBytesToIntegerLE(bytes, startIndex, size);
        } else if (size == 4) {
            return bytesToIntegerLE(bytes, startIndex);
        } else {
            checkInputParametersValidation(bytes, startIndex, startIndex + size, 5, 7);

            int index = startIndex + size - 1;
            long value0 = ((long) bytes[index--] << 56) & 0xFF00000000000000L;
            long value1 = ((long) bytes[index--] << 48) & 0xFF000000000000L;
            long value2 = ((long) bytes[index--] << 40) & 0xFF0000000000L;
            long value3 = ((long) bytes[index--] << 32) & 0xFF00000000L;
            long value4 = ((long) bytes[index--] << 24) & 0xFF000000L;
            long value5 = 0;
            long value6 = 0;
            if (size > 5) {
                value5 = (bytes[index--] << 16) & 0xFF0000;
                if (size > 6) {
                    value6 = (bytes[index] << 8) & 0xFF00;
                }
            }

            int offset = 8 - size;
            return (value0 | value1 | value2 | value3 | value4 | value5 | value6) >>> (offset * 8);
        }
    }

    //endregion

    //endregion

    //region Byte Array Utils

    /**
     * 将整个字节数组向右无符号位移指定的位数
     *
     * @param source 原始数组，长度大于0
     * @param offset 位移量，范围：1~7
     * @return 位移后的数组
     * @throws IllegalArgumentException 输入参数为空或无效
     */
    public static byte[] byteArrayRightShift(byte[] source, int offset) throws IllegalArgumentException {
        if (source == null || source.length == 0) {
            throw new IllegalArgumentException("'source' must not be null or empty!");
        } else {
            if (offset >= 1 && offset <= 7) {
                byte buffer = 0;
                int temp = 0;
                byte[] newArray = new byte[source.length];
                for (int i = 0; i < newArray.length; i++) {
                    byte value = source[i];
                    temp = (value >>> offset) & (0xFF >>> offset);
                    newArray[i] = (byte) (buffer | temp);
                    buffer = (byte) (value << offset);
                }
                return newArray;
            } else {
                throw new IllegalArgumentException("'offset' must greater or equals than 1 and less or equals than 7!");
            }
        }
    }

    //endregion

    //endregion

    //region Private Methods

    /**
     * 检查输入参数的有效性
     *
     * @param bytes      原始数据
     * @param startIndex 起始序号
     * @param size       需要的大小
     * @throws IllegalArgumentException 输入参数异常
     */
    private static void checkInputParametersValidation(final byte[] bytes, int startIndex, int size) throws IllegalArgumentException {
        if (bytes == null) {
            throw new IllegalArgumentException("bytes cannot be null!");
        } else if (startIndex < 0) {
            throw new IllegalArgumentException("startIndex cannot be negative!");
        } else if (bytes.length < startIndex + size) {
            throw new IllegalArgumentException("bytes size not enough!");
        }
    }

    /**
     * 检查输入参数的有效性
     *
     * @param bytes      原始数据
     * @param startIndex 起始序号
     * @param size       需要的大小
     * @throws IllegalArgumentException 输入参数异常
     */
    private static void checkInputParametersValidation(final byte[] bytes, int startIndex, int size, int min, int max) throws IllegalArgumentException {
        if (bytes == null) {
            throw new IllegalArgumentException("bytes cannot be null!");
        } else if (startIndex < 0) {
            throw new IllegalArgumentException("startIndex cannot be negative!");
        } else if (bytes.length < startIndex + size) {
            throw new IllegalArgumentException("bytes size not enough!");
        } else if (bytes.length < min || bytes.length > max) {
            throw new IllegalArgumentException("bytes size not valid!");
        }
    }

    //endregion
}